package cn.wolfcode.p2p.business.service.impl;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;

import cn.wolfcode.p2p.base.domain.Account;
import cn.wolfcode.p2p.base.domain.UserInfo;
import cn.wolfcode.p2p.base.service.IAccountService;
import cn.wolfcode.p2p.base.service.IUserInfoService;
import cn.wolfcode.p2p.base.util.BitStateUtil;
import cn.wolfcode.p2p.base.util.Constants;
import cn.wolfcode.p2p.base.util.UserContext;
import cn.wolfcode.p2p.business.domain.MoneyWithdraw;
import cn.wolfcode.p2p.business.domain.UserBankinfo;
import cn.wolfcode.p2p.business.mapper.MoneyWithdrawMapper;
import cn.wolfcode.p2p.business.query.MoneyWithdrawQueryObject;
import cn.wolfcode.p2p.business.service.IAccountFlowService;
import cn.wolfcode.p2p.business.service.IMoneyWithdrawService;
import cn.wolfcode.p2p.business.service.ISystemAccountService;
import cn.wolfcode.p2p.business.service.IUserBankinfoService;

@Service
@Transactional
public class MoneyWithdrawServiceImpl implements IMoneyWithdrawService {

	@Autowired
	private MoneyWithdrawMapper withdrawMapper;

	@Autowired
	private IUserInfoService userinfoService;

	@Autowired
	private IAccountService accountService;

	@Autowired
	private IAccountFlowService flowService;

	@Autowired
	private IUserBankinfoService bankinfoService;

	@Autowired
	private ISystemAccountService systemAccountService;

	@Override
	public PageInfo<MoneyWithdraw> query(MoneyWithdrawQueryObject qo) {
		PageHelper.startPage(qo.getCurrentPage(), qo.getPageSize());
		List<MoneyWithdraw> list = this.withdrawMapper.queryData(qo);
		return new PageInfo<>(list);
	}

	@Override
	public void apply(BigDecimal moneyAmount) {
		UserInfo current = this.userinfoService.get(UserContext.getCurrent().getId());
		Account account = this.accountService.get(current.getId());
		// 判断,
		if (!current.getHasWithdrawInProcess()// 1,没有提现在审核流程当中;
				&& moneyAmount.compareTo(account.getUsableAmount()) <= 0// 提现金额<=账户余额
				&& moneyAmount.compareTo(Constants.WITHDRAW_AMOUNT_MIN) >= 0// 最小提现金额<=提现金额
				&& current.getHasBindBankInfo()// 绑定银行卡
		) {
			// 创建一个提现对象,设置相关属性;
			MoneyWithdraw mw = new MoneyWithdraw();

			UserBankinfo bankinfo = this.bankinfoService.getByUserId(current.getId());
			mw.setAccountName(bankinfo.getAccountName());
			mw.setAccountNumber(bankinfo.getAccountNumber());
			mw.setApplier(UserContext.getCurrent());
			mw.setApplyTime(new Date());
			mw.setBankForkName(bankinfo.getBankForkName());
			mw.setBankName(bankinfo.getBankName());

			mw.setFee(Constants.WITHDRAW_FEE);
			mw.setMoneyAmount(moneyAmount);
			mw.setState(MoneyWithdraw.STATE_NORMAL);
			this.withdrawMapper.insert(mw);
			// 账户可用余额减少,冻结金额增加;

			account.setUsableAmount(account.getUsableAmount().subtract(moneyAmount));
			account.setFreezedAmount(account.getFreezedAmount().add(moneyAmount));
			// 生成提现申请流水;
			this.flowService.createWithdrawFlow(account, mw);
			this.accountService.update(account);
			// 添加状态吗
			current.addState(BitStateUtil.HAS_WITHDRAW_IN_PROCESS);
			this.userinfoService.update(current);
		}
	}

	@Override
	public void audit(Long id, int state, String remark) {
		MoneyWithdraw mw = this.withdrawMapper.selectByPrimaryKey(id);
		// 判断,处于待审核状态
		if (mw != null && mw.getState() == MoneyWithdraw.STATE_NORMAL) {
			// 设置审核相关属性;
			mw.setAuditor(UserContext.getCurrent());
			mw.setAuditTime(new Date());
			mw.setRemark(remark);
			mw.setState(state);
			this.withdrawMapper.updateByPrimaryKey(mw);

			// 1,去掉用户状态吗
			UserInfo applier = this.userinfoService.get(mw.getApplier().getId());
			applier.removeState(BitStateUtil.HAS_WITHDRAW_IN_PROCESS);
			this.userinfoService.update(applier);
			// 如果审核通过
			Account account = this.accountService.get(applier.getId());
			if (state == MoneyWithdraw.STATE_PASS) {
				// 1,冻结金额减少,生成提现成功流水;
				BigDecimal withDrawAmount = mw.getMoneyAmount().subtract(mw.getFee());
				account.setFreezedAmount(account.getFreezedAmount().subtract(withDrawAmount));
				this.flowService.createWithdrawSuccessFlow(account, mw);
				// 2,冻结金额减少,生成支付提现手续费流水;
				account.setFreezedAmount(account.getFreezedAmount().subtract(mw.getFee()));
				this.flowService.createWithdrawFeeFlow(account, mw);
				// 3,系统收取提现手续费,生成系统流水
				this.systemAccountService.chargeWithdrawFee(mw);
			} else {
				// 如果审核拒绝
				// 1,取消冻结金额
				account.setFreezedAmount(account.getFreezedAmount().subtract(mw.getMoneyAmount()));
				account.setUsableAmount(account.getUsableAmount().add(mw.getMoneyAmount()));
				// 2,生成提现失败流水
				this.flowService.createWithdrawFaildFlow(account, mw);
			}
			this.accountService.update(account);
		}
	}

}
